import { _decorator, Component, director, Label, Node } from 'cc';
import DataManager from '../Runtime/DataManager';
import { ApiMsgEnum, EntityTypeEnum, IMsgGameStart, IMsgRoomSync, IRoom, StateTypeEnum } from '../Common';
import { createUINode } from '../Utils';
import { ActorManager } from '../Entity/Actor/ActorManager';
import { NetworkManager } from '../Runtime/NetworkManager';
import { SceneEnum } from '../Enum';
import { showToast } from '../Runtime/MainManager';
import { BattleScene } from './BattleScene';
const { ccclass, property } = _decorator;

@ccclass('RoomManager')
export class RoomManager extends Component {

    @property(Node)
    button_gameStart: Node

    @property(Node)
    button_ready: Node

    @property(Node)
    button_cancelReady: Node

    @property(Node)
    button_joinGame: Node

    @property(Node)
    button_leave: Node

    @property([Node])
    playerNode: Node[] = []

    private actors = [
        EntityTypeEnum.actor_red,
        EntityTypeEnum.actor_blue,
        EntityTypeEnum.actor_green,
        EntityTypeEnum.actor_yellow,
    ]

    private data: IRoom

    async onLoad() {
        director.preloadScene(SceneEnum.Battle)

        for (const i in this.playerNode) {
            const lab = this.playerNode[i].getComponentInChildren(Label)
            lab.string = ''
        }
        this.data = DataManager.Ins.roomInfo
        this.render()
        NetworkManager.Ins.listening(ApiMsgEnum.MsgRoomSync, this.handelMsgRoomSync, this)
        NetworkManager.Ins.listening(ApiMsgEnum.MsgGameStart, this.handelMsgGameStart, this)
    }

    handelMsgRoomSync(res: IMsgRoomSync) {
        DataManager.Ins.roomInfo = res.room
        this.data = DataManager.Ins.roomInfo
        this.render()
    }

    handelMsgGameStart(res: IMsgGameStart) {
        DataManager.Ins.state = res.state
        // DataManager.Ins.lastState = deepClone(DataManager.Ins.state)
        director.loadScene(SceneEnum.Battle, (e, scene) => {
            if (e) {
                console.log(e)
                return
            }
            scene.getComponentInChildren(BattleScene).init()
        })
    }

    onGameStart() {
        NetworkManager.Ins.callApi(ApiMsgEnum.ApiGameStart, {}).then((data) => {
            const { success, res, error } = data
            if (!success) {
                showToast(error)
                console.log(error)
                return
            }
        })
    }
    onReady() {
        NetworkManager.Ins.callApi(ApiMsgEnum.ApiPlayerReady, {}).then((data) => {
            const { success, res, error } = data
            if (!success) {
                showToast(error)
                console.log(error)
                return
            }
        })
    }
    onCancelReady() {
        NetworkManager.Ins.callApi(ApiMsgEnum.ApiPlayerCancelReady, {}).then((data) => {
            const { success, res, error } = data
            if (!success) {
                showToast(error)
                console.log(error)
                return
            }
        })
    }
    /** 中途加入游戏 */
    onJoinGame() {
        director.loadScene(SceneEnum.Battle, (err, scene) => {
            if (err) {
                console.log(err)
                return
            }
            scene.getComponentInChildren(BattleScene).applyMidJoinGame()
        })
    }
    /** 离开房间 */
    onLeave() {
        NetworkManager.Ins.callApi(ApiMsgEnum.ApiRoomLeave, {}).then((data) => {
            const { success, res, error } = data
            if (!success) {
                showToast(error)
                console.log(error)
                return
            }
            director.loadScene(SceneEnum.Hall)
        })
    }

    render() {

        const myself = this.data.players.find(v => v.id === DataManager.Ins.myId)
        this.button_gameStart.active = myself.id === this.data.players[0].id && !this.data.isGaming
        this.button_ready.active = myself.id !== this.data.players[0].id && myself.ready == 0 && !this.data.isGaming
        this.button_cancelReady.active = myself.id !== this.data.players[0].id && myself.ready == 1 && !this.data.isGaming
        this.button_joinGame.active = this.data.isGaming

        for (const i in this.playerNode) {
            const lab = this.playerNode[i].getComponentInChildren(Label)
            const actor = this.playerNode[i].getChildByName('actor')
            lab.string = ''
            actor.removeAllChildren()
            if (this.data.players[i]) {
                const { nickName, id, ready } = this.data.players[i]
                lab.string = nickName

                const type = this.actors[i]
                const node = createUINode(type)
                const am = node.addComponent(ActorManager)
                am.init({
                    id,
                    nickName,
                    type,
                    position: { x: 0, y: 0 },
                    direction: { x: 1, y: 0 },
                    hp: 0,
                    state: StateTypeEnum.none,
                    skillPoint: 0,
                    beHitCD: 0,
                    attr: {
                        hpMax: 0,
                        defense: 0,
                        damage: 0,
                        growth: 0,
                        regeneration: 0,
                        knckback: 0,
                        range: 0,
                        fireRate: 0,
                        lootRange: 0,
                        critRate: 0,
                        critChance: 0,
                        moveSpeed: 0,
                        hpMaxRate: 0,
                        defenseRate: 0,
                        damageRate: 0
                    },
                    skill: [],
                    regenerationCD: 0
                })
                node.parent = actor

                if (ready === 1) {
                    am.fsm.currencyState = am.fsm.stateMachines.get(StateTypeEnum.run)
                } else {
                    am.fsm.currencyState = am.fsm.stateMachines.get(StateTypeEnum.idle)
                }
            }
        }
    }

    onDestroy() {
        NetworkManager.Ins.unlistening(ApiMsgEnum.MsgRoomSync, this.handelMsgRoomSync, this)
        NetworkManager.Ins.unlistening(ApiMsgEnum.MsgGameStart, this.handelMsgGameStart, this)
    }
}


